package obecto.container
{
	import flash.geom.Rectangle;
	
	import obecto.core.FLContainer;
	import obecto.event.FLEvent;

	public class ClippingContainer extends FLContainer
	{
		[Bindable]
		override public function set width(value : Number) : void
		{
			clippingRect.width = value;
			if (initialized)
			{
				updateScrollRect();
			}
			else
			{
				initializationScrollRectChanged = true;
			}
		}
		override public function get width() : Number
		{
			return clippingRect.width;
		}
		
		[Bindable]
		override public function set height(value : Number) : void
		{
			clippingRect.height = value;
			if (initialized)
			{
				updateScrollRect();
			}
			else
			{
				initializationScrollRectChanged = true;
			}
		}
		override public function get height() : Number
		{
			return clippingRect.height;
		}
	
		[Bindable]
		public function set scrollX(value : Number) : void
		{
			clippingRect.x = value;
			if (initialized)
			{
				updateScrollRect();
			}
			else
			{
				initializationScrollRectChanged = true;
			}
		}
		public function get scrollX() : Number
		{
			return clippingRect.x;
		}
		
		[Bindable]
		public function set scrollY(value : Number) : void
		{
			clippingRect.y = value;
			if (initialized)
			{
				updateScrollRect();
			}
			else
			{
				initializationScrollRectChanged = true;
			}
		}
		public function get scrollY() : Number
		{
			return clippingRect.y;
		}
		
		protected var clippingRect : Rectangle = new Rectangle();
		protected var originalRect : Rectangle = new Rectangle();;
		protected var initializationScrollRectChanged : Boolean = false;
		
		public function ClippingContainer()
		{
			super();
			
			// initially the component is invisible to avoid any visual glitches with the lazy setting of the scrollRect:
			visible = false;
			
			addEventListener(FLEvent.CREATION_COMPLETE, handleCreationComplete);
		}
		
		public function updateScrollRect() : void 
		{
			// ensuring that the clipping width and height are smaller than the component's dimensions:
			var clipWidth : Number = clippingRect.width != 0 ?
				Math.min(originalRect.width, clippingRect.width) : 
				originalRect.width;
			var clipHeight : Number = clippingRect.height != 0 ?
				Math.min(originalRect.height, clippingRect.height) : 
				originalRect.height;
			
			// ensuring that the scrollX and scrollY are within the valid dimensions:
			var clipX : Number = Math.min(originalRect.width - clipWidth, clippingRect.x);
			var clipY : Number = Math.min(originalRect.height - clipHeight, clippingRect.y);
			
			clippingRect.x = Math.round(clipX);
			clippingRect.y = Math.round(clipY);
			clippingRect.width = Math.round(clipWidth);
			clippingRect.height = Math.round(clipHeight);
			
			scrollRect = clippingRect;
		}
		
		protected function handleCreationComplete(e : FLEvent) : void 
		{
			originalRect.width = super.width;
			originalRect.height = super.height;
			if (!initializationScrollRectChanged)
			{
				clippingRect.width = super.width;
				clippingRect.height = super.height;
			}
			updateScrollRect();
			visible = true;
		}
		
	}
}